import Head from 'next/head'
import { useEffect, useState, useRef } from 'react';
import { useRouter } from 'next/router'
import { Form, Button, ListGroup, Image} from 'react-bootstrap';
import Styles from '../../../../../styles/movies.video.module.css';
import Router from 'next/router';
import cookies from 'next-cookies'
import HlsPlayer from '../../../../../components/hlsPlayer';
import VideoTrailer from '.././../../../../components/videoTrailer';
import validateServerAccess from '../../../../../lib/validateServerAccess';
import Actor from '../../../../../components/actor';
import useWindowSize from '../../../../../components/hooks/WindowSize';
import MovieBackdrop from '../../../../../components/movieBackdrop';
import ChangeImages from '../../../../../components/changeImages';


export default function Home(props) {
  const server = props.server;
  const router = useRouter();
  const { id } = router.query;
  const serverToken = props.serverToken;
  const [metadata, setMetadata] = useState({});
  const [watched, setWatched] = useState(false);
  const [inWatchList, setInWatchList] = useState(false);
  const [actors, setActors] = useState([]);
  const [recommended, setRecommended] = useState([]);

  const [viewTrailer, setViewTrailer] = useState(false);
  const [trailer, setTrailer] = useState(false);

  const [loaded, setLoaded] = useState(false)
  const [recommendedLoaded, setRecommendedLoaded] = useState(false);

  const videoRef = useRef();
  const windowSize = useWindowSize();



  // Used for manual metadata search
  const [metadataBox, setMetadataBox] = useState(false);
  const [metadataSearchResult, setMetadataSearchResult] = useState([]);
  const metadataSearch = useRef(null);



  // This has it's own useEffect because if it doesn't videojs doesn't work (????)
  useEffect(() => {
    validateServerAccess(server, (serverToken) => {
      fetch(`${server.server_ip}/api/movies/${id}/getRecommended?token=${serverToken}`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        }
      })
      .then(r => r.json())
      .then(result => {
        if (result.success) {
          console.log(result);
          result.movies.forEach(movie => {
            for (let image of movie.images) {
                if (image.active) {
                    if (image.type === 'BACKDROP') {
                        if (image.path === 'no_image') {
                            movie.backdrop = null;
                        } else {
                            movie.backdrop = image.path;
                        }
                    } else {
                        if (image.path === 'no_image') {
                            movie.backdrop = null;
                        } else {
                            movie.poster = image.path;
                        }
                    }

                    if (movie.backdrop != null && movie.poster != null) {
                        break;
                    }
                }
            }
        });
          setRecommended(result.movies);
        }
      })
      .then(() => {
        setRecommendedLoaded(true);
      });



      fetch(`${server.server_ip}/api/movies/${id}?token=${serverToken}`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        }
      })
      .then(r => r.json())
      .then(result => {
        let meta = result.result;
        console.log(meta)
        let finish_at = new Date(new Date().getTime() + meta.runtime * 60000);
        meta.finish_at = finish_at.getHours() + ":" + finish_at.getMinutes();
        for (let image of meta.images) {
          if (image.active && image.type === 'BACKDROP') {
            meta.backdrop = image.path;
          }
          if (image.active && image.type === 'POSTER') {
            meta.poster = image.path;
          }
        }
        
        let new_added_date = new Date(parseInt(meta.added_date));
        let added_year = new_added_date.getFullYear();
        let added_month = new_added_date.getMonth() + 1;
        if(added_month < 10) {
          added_month = "0" + added_month.toString();
        }
        let adde_date = new_added_date.getDate();
        if(adde_date < 10) {
          adde_date = "0" + adde_date.toString();
        }
        meta.added_date = `${added_year}-${added_month}-${adde_date}`
  
        let currentTime = "";
        let hours = Math.floor(meta.currentTime / 60 / 60)
        let minutes = Math.floor((meta.currentTime / 60) % 60)
        let seconds = Math.floor(meta.currentTime % 60);
        if (hours >= 1) {
          currentTime += `${hours}:`
        }
        if (minutes < 10) {
          minutes = `0${minutes}`;
        }
        if (seconds < 10) {
          seconds = `0${seconds}`
        }
        currentTime += `${minutes}:${seconds}`
        meta.currentTimeSeconds = meta.currentTime;
        meta.currentTime = currentTime;
        console.log(videoRef)
        videoRef.current.setTitle(meta.title);
  
        setInWatchList(meta.inwatchlist);
        setWatched(meta.watched);
        setMetadata(meta);
        setTrailer(meta.trailer);
        meta.actors = meta.actors.sort((a, b) => {
          return parseFloat(a.order) - parseFloat(b.order);
        });
        setActors(meta.actors);

        if (router.query.autoPlay) {
          videoRef.current.show();
        }
      }).then(() => {
        setLoaded(true)
      });
    });
  }, []);

  const markAsWatched = () => {
    validateServerAccess(server, (serverToken) => {
      fetch(`${server.server_ip}/api/movies/${id}/setWatched?watched=true&token=${serverToken}`)
      .then(r => r.json())
      .then(status => {
        if (status.success) {
          setWatched(true);
        } else {
          console.log("ERROR MARKING AS WATCHED: " + status);
        }
      }).catch(err => {
        console.log(err);
      });
    });

  }

  const markAsNotWatched = () => {
    validateServerAccess(server, (serverToken) => {
      fetch(`${server.server_ip}/api/movies/${id}/setWatched?watched=false&token=${serverToken}`)
      .then(r => r.json())
      .then(status => {
        if (status.success) {
          setWatched(false);
        } else {
          console.log("ERROR MARKING AS WATCHED: " + status);
        }
      })
      .catch(err => {
        console.log(err);
      });
    });
  }

  const addToWatchList = () => {
    validateServerAccess(server, (serverToken) => {
      fetch(`${server.server_ip}/api/movies/${id}/addToWatchList?add=true&token=${serverToken}`)
      .then(r => r.json())
      .then(status => {
        if (status.success) {
          setInWatchList(true);
        } else {
          console.log("ERROR adding to watchlist: " + status);
        }
      })      .catch(err => {
        console.log(err);
      });
    });
  }

  const removeFromWatchList = () => {
    validateServerAccess(server, (serverToken) => {
      fetch(`${server.server_ip}/api/movies/${id}/addToWatchList?add=false&token=${serverToken}`)
      .then(r => r.json())
      .then(status => {
        if (status.success) {
          setInWatchList(false);
        } else {
          console.log("ERROR removing from watchlist: " + status);
        }
      })
      .catch(err => {
        console.log(err);
      });
    });
  }

  const searchMetadata = (event) => {
    let search = metadataSearch.current.value;
    if(search != ""){
      validateServerAccess(server, (serverToken) => {
        fetch(`${server.server_ip}/api/movies/searchMetadata?search=${search}&token=${serverToken}`)
        .then(r => r.json())
        .then(result => {
          console.log(result);
          let metadataElements = [];
          for (let movie of result) {
            const img = movie.poster_path !== null ? `https://image.tmdb.org/t/p/w500/${movie.poster_path}` : 'https://via.placeholder.com/500x750' 
            metadataElements.push(
              <ListGroup.Item key={movie.id} className={Styles.metadataSearchRow} data-metadataid={movie.id}>
                <Image src={img} alt="" />
                <div>
                  <h5>{movie.title}</h5>
                  <p>{movie.overview}</p>
                </div>
                <Button onClick={() => updateMetadata(movie.id)}>Välj</Button>
              </ListGroup.Item>
            );        
          }
          setMetadataSearchResult(metadataElements);
        });
      });
    }
   
    event.preventDefault();
  }

  const updateMetadata = (metadataID) => {
    validateServerAccess(server, (serverToken) => {
      fetch(`${server.server_ip}/api/movies/${id}/updateMetadata?metadataID=${metadataID}&token=${serverToken}`)
      .then(r => r.json())
      .then(json => {
        if (json.success) {
          Router.reload(window.location.pathname);
        }
      });
    });
  }


  const getActors = () => {
    let elements = [];
    for (const actor of actors) {
      elements.push(
        <Actor key={actor.order} name={actor.name} characterName={actor.character} image={actor.image} />
      )
    }
    return elements;
  }

  const getRecommended = () => {
    let elements = [];
    for (const movie of recommended) {
      let img = movie.backdrop !== null ? `https://image.tmdb.org/t/p/w500/${movie.backdrop}` : 'https://via.placeholder.com/2000x1000' 
      elements.push(
          <MovieBackdrop markAsDoneButton id={movie.id} time={0} runtime={0} title={movie.title} overview={movie.overview} backdrop={img} onClick={(id) => selectMovie(movie.id)}></MovieBackdrop>
      );
    }
    return elements;
  }

  const selectMovie = (id) => {
    Router.push(`/server/${server.server_id}/movies/video/${id}`);
    Router.events.on("routeChangeComplete", () => {
      Router.reload(window.location.pathname);


    });
  }
  
  const scrollLeft = (id) => {
    document.getElementById(id).scrollLeft -= (window.innerWidth)*0.8;
    window.scrollTo(window.scrollX, window.scrollY - 1);
    window.scrollTo(window.scrollX, window.scrollY + 1);
  }
  const scrollRight = (id) => {
      document.getElementById(id).scrollLeft += (window.innerWidth)*0.8;
      window.scrollTo(window.scrollX, window.scrollY - 1);
      window.scrollTo(window.scrollX, window.scrollY + 1);
  }
  return (
    <>
    <HlsPlayer
      ref={videoRef}
      server={server}
      id={id}
      type={"movie"}>

    </HlsPlayer>
   
    {(!loaded || !recommendedLoaded) &&
    <>
      <Head>
        <title>Dose</title>
      </Head>
      <div className={Styles.loadingioSpinnerEclipse}>
          <div className={Styles.ldio}>
              <div></div>
          </div>
      </div>
    </>
    }
    {loaded && recommendedLoaded && 
    <>


  <Head>
      <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap" rel="stylesheet" />
      <title>{metadata.title + " (" + metadata.release_date.split('-')[0] + ")"}</title>
      <meta name="title" content={metadata.title + " (" + metadata.release_date + ")"} />
      <meta name="description" content={metadata.overview} />

      <meta property="og:type" content="website" />
      <meta property="og:title" content={metadata.title + " (" + metadata.release_date.split('-')[0] + ")"} />
      <meta property="og:description" content={metadata.overview} />
      <meta property="og:image" content={"https://image.tmdb.org/t/p/original" + metadata.backdrop} />

      <meta property="twitter:card" content="summary_large_image" />
      <meta property="twitter:title" content={metadata.title + " (" + metadata.release_date.split('-')[0] + ")"} />
      <meta property="twitter:description" content={metadata.overview} />
      <meta property="twitter:image" content={"https://image.tmdb.org/t/p/original" + metadata.backdrop} />
    </Head>

    {trailer !== false && viewTrailer &&
    <VideoTrailer onClose={() => setViewTrailer(false)} videoPath={trailer} />
    }


    <div id="container">
    <div style={{backgroundImage: `url('https://image.tmdb.org/t/p/original${metadata.backdrop}')`}} className={Styles.background}></div>
    <div className="backIcon" onClick={() => {
      Router.back();
      Router.events.on("routeChangeComplete", () => {
        Router.reload(window.location.pathname);
      });
      }}></div>


    {metadataBox &&
      <div className="metadataBox">
        <Form onSubmit={searchMetadata}>
          <Form.Group controlId="formSearch">
            <Form.Label>Update metadata for {metadata.path}</Form.Label>
            <Form.Control ref={metadataSearch} type="text" placeholder="Search for new metadata..." />
          </Form.Group>
          <Button variant="primary" type="submit">
            Search
          </Button>
        </Form>
        <div style={{clear: 'both'}}></div>

        <ListGroup id="metadataSearchResult">
          {metadataSearchResult}
        </ListGroup>
      </div>
    }


    <div className={Styles.top}>
      <div className={Styles.poster} style={{backgroundImage: `url('https://image.tmdb.org/t/p/original${metadata.poster}')`}} />
      <div className={Styles.description}>
        <h1>{metadata.title}</h1>
        <div className={Styles.metadata}>
          <p className={Styles.releaseDate}>{metadata.release_date}</p>
          <p className={Styles.runtime}>{Math.floor(metadata.runtime / 60) + "h " + metadata.runtime%60+"m"}</p>
          <p className={Styles.endsat}>Ends At {metadata.finish_at}</p>
          <p className={Styles.addedDate}>Added {metadata.added_date}</p>
        </div>
        <div className={Styles.overview}>
            <p>{metadata.overview}</p>
        </div>
        <div className={Styles.actions}>
          {metadata.currentTimeSeconds > 0 &&
          <div style={{marginRight: "15px"}} className={Styles.actionButton}>
            <div className={Styles.playButton} onClick={() => videoRef.current.show(metadata.currentTimeSeconds)}></div>
            <p style={{marginTop: "5px", fontSize: '14px'}}>Resume from {metadata.currentTime}</p>
          </div>
          }
          <div style={{marginRight: "15px"}} className={Styles.actionButton}>
            <div className={Styles.playButton} onClick={() => videoRef.current.show()}></div>
            <p style={{marginTop: "5px", fontSize: '14px'}}>Play from start</p>
          </div>
          <div className={`${Styles.actionButton} ${Styles.buttonHiddenForMobile}`}>
            <div className={Styles.playButton} onClick={() => setViewTrailer(true)}></div>
            <p style={{marginTop: "5px", fontSize: '14px'}}>Show trailer</p>
          </div>
          {watched &&
              <div style={{marginLeft: "15px"}} className={Styles.actionButton}>
              <div id="markAsWatched" style={{backgroundImage: `url('${process.env.NEXT_PUBLIC_SERVER_URL}/images/cross.svg')`}} className={Styles.playButton} onClick={() => markAsNotWatched()}></div>
              <p id="markAsWatchedText" style={{marginTop: "5px", fontSize: '14px'}}>Mark as watched</p>
              </div>
          }
          {!watched &&
            <div style={{marginLeft: "15px"}} className={Styles.actionButton}>
              <div id="markAsWatched" style={{backgroundImage: `url('${process.env.NEXT_PUBLIC_SERVER_URL}/images/eye.svg')`}} className={Styles.playButton} onClick={() => markAsWatched()}></div>
              <p id="markAsWatchedText" style={{marginTop: "5px", fontSize: '14px'}}>Unmark as watched</p>
            </div>
          }
          {inWatchList &&
              <div style={{marginLeft: "15px"}} className={Styles.actionButton}>
              <div id="inWatchList" style={{backgroundImage: `url('${process.env.NEXT_PUBLIC_SERVER_URL}/images/cross.svg')`}} className={Styles.playButton} onClick={() => removeFromWatchList()}></div>
              <p id="inWatchListText" style={{marginTop: "5px", fontSize: '14px'}}>Remove from watchlist</p>
              </div>
          }
          {!inWatchList &&
            <div style={{marginLeft: "15px"}} className={Styles.actionButton}>
              <div id="inWatchList" style={{backgroundImage: `url('${process.env.NEXT_PUBLIC_SERVER_URL}/images/eye.svg')`}} className={Styles.playButton} onClick={() => addToWatchList()}></div>
              <p id="inWatchListText" style={{marginTop: "5px", fontSize: '14px'}}>Add to watchlist</p>
            </div>
          }
          <div className={`${Styles.actionButton} ${Styles.buttonHiddenForMobile}`}>
            <div style={{marginLeft: "15px", backgroundImage: `url('${process.env.NEXT_PUBLIC_SERVER_URL}/images/search.svg')`}} className={Styles.playButton} onClick={() => setMetadataBox(true)}></div>
            <p style={{marginLeft: "15px", marginTop: "5px", fontSize: '14px'}}>Update metadata</p>
          </div>

          <ChangeImages  id={id} server={server} serverToken={serverToken} type="movies"></ChangeImages>
          <div style={{clear: 'both'}}></div>
        </div>
      </div>
    </div>
    <div className={Styles.bottom}>
      <h1>Actors</h1>
      <div className={Styles.actors}>
        <div id="actors" className={Styles.actorBox}>
          {getActors()}
        </div>
        {actors.length * 200 > windowSize.width &&
                                <>
                                    <div className={Styles.scrollButton} onClick={() => scrollLeft('actors')}>
                                        <img alt="" src={`${process.env.NEXT_PUBLIC_SERVER_URL}/images/left.svg`} width="70" height="70" />
                                    </div>
                                    <div className={Styles.scrollButton} style={{right: '0'}} onClick={() => scrollRight('actors')}>
                                        <img alt="" src={`${process.env.NEXT_PUBLIC_SERVER_URL}/images/right.svg`} width="70" height="70" />
                                    </div>
                                </>
                            }
      </div>

    <h1>Recommended</h1>
    {recommended.length > 0 &&
                    <div style={{position: 'relative'}}>
                        <div className={Styles.movieRow}>
                            <div id="recommended" className={Styles.scrollable}>
                                {getRecommended()}
                            </div>
                            {recommended.length * 480 > windowSize.width &&
                                <div>
                                    <div className={Styles.scrollButton} onClick={() => scrollLeft('recommended')}>
                                        <img alt="" src={`${process.env.NEXT_PUBLIC_SERVER_URL}/images/left.svg`} width="70" height="70" />
                                    </div>
                                    <div className={Styles.scrollButton} style={{right: '0'}} onClick={() => scrollRight('recommended')}>
                                        <img alt="" src={`${process.env.NEXT_PUBLIC_SERVER_URL}/images/right.svg`} width="70" height="70" />
                                    </div>
                                </div>
                            }
                        </div> 
                    <hr className={Styles.divider}></hr>
                    </div> 
                }
    </div>
    </div>
    </>
    }
    </>
  )
}

// Get the information about the server and send it to the front end before render (this is server-side)
export async function getServerSideProps(context) {
  let serverId = context.params.server;
  let movieID = context.params.id;

  return await fetch(`http://localhost:${process.env.SERVER_PORT}${process.env.SERVER_SUB_FOLDER}/api/servers/getServer`, {
      method: 'POST',
      headers: {
          'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          id: serverId
      }),
  })
  .then((r) => r.json())
  .then(async (data) =>{
    return {
      props: {
          server: data.server,
          serverToken: cookies(context).serverToken || ''
      }
    }

  });
}